//  Copyright (c) 2020-present,  INSPUR Co, Ltd.  All rights reserved.
// This source code is licensed under Apache 2.0 License.

#pragma once

#include <algorithm>
#include <iostream>
#include <vector>
#include "pure_mem/memoryblock/memory_arena/memory_arena.h"
#include "rocksdb/slice.h"

namespace rocksdb {

struct Node {
    Slice startKey;
    void *memory_arena = nullptr;

    Node(const Slice &key, IMemoryArena *memoryarena) {
        char* buf = new char[key.size()];
        memcpy(buf, key.data(), key.size());
        startKey = Slice(buf, key.size());
        memory_arena = memoryarena;
    }
    ~Node(){
        delete [] startKey.data();
    }
    /*bool operator == (const Node &n){
        return (this->memory_arena == n.memory_arena) && (this->startKey == n.startKey);
    }
    bool operator == (const Slice &key){
        return (this->startKey == key);
    }*/
};

class Vector {
public:
    std::vector<struct Node>::iterator iter;
public:
    Vector() {};
    Vector(size_t len);
    ~Vector();
    int32_t Seek(const Slice &key);
    int32_t SeekForPrev(const Slice &key);
    bool Insert(Node node);
    bool Insert(Node preNode, Node node);
    void *GetMemArenaAddr(size_t index);

private:
    std::vector<struct Node> vec;
};

Vector::Vector(size_t len) {
    vec.reserve(len);
}

Vector::~Vector() {
    std::vector<struct Node>().swap(vec);
}

int32_t Vector::Seek(const Slice &key) {
    if (vec.empty() || key.empty()) { // || or && ????
        std::cout << "current vector or key is empty !" << std::endl;
        return -2;
    }
    int32_t start = 0, end = vec.size() - 1;
    while (start <= end) {
        int32_t mid = (start + end) / 2;
        if (vec[mid].startKey == key) {
            return mid;
        }
        if (vec[mid].startKey.compare(key) < 0) {
            start = mid + 1;
        } else {
            end = mid - 1;
        }
    }
    std::cout << "current key not exists !" << std::endl;
    return -1;
}

int32_t Vector::SeekForPrev(const Slice &key) {
    assert(!key.empty());
    if (vec.empty()) {  // || or && ????
        std::cout << "current vector or key is empty !" << std::endl;
        return -2;  // 全部值都大于key时，会返回-1，产生冲突。
    }
    int32_t start = 0, end = vec.size() - 1;
    while (start <= end) {
        int32_t mid = (start + end) / 2;
        if (vec[mid].startKey == key) {
            return mid;
        }
        if (vec[mid].startKey.compare(key) < 0) {
            start = mid + 1;
        } else {
            end = mid - 1;
        }
    }
    return start - 1;
}

bool Vector::Insert(Node node) {
    int32_t index = SeekForPrev(node.startKey);
    if (index >= 0) {  //正常找到preKey的位置
        if (vec[index].startKey == node.startKey) {
            vec[index].memory_arena = node.memory_arena;
        }
        vec.insert(vec.begin() + index + 1, node);
        return true;
    } else if (index == -2) {
        vec.push_back(node);
        return true;
    } else {
        std::cout << "wrong insert!" << std::endl;
        return false;
    }
}

bool Vector::Insert(Node preNode, Node node) {
    assert(preNode.startKey != node.startKey);
    int32_t index = Seek(preNode.startKey);
    if (index >= 0) {  //正常找到preKey的位置
        vec[index] = preNode;
        vec.insert(vec.begin() + index + 1, node);
        return true;
    } else if (index == -2) {
        vec.push_back(node);
        return true;
    } else {
        std::cout << "wrong insert!" << std::endl;
        return false;
    }
}

void * Vector::GetMemArenaAddr(size_t index) {
    return vec[index].memory_arena;
}
}